package service.Impl;

import enmu.ItemType;
import enmu.ModifiedType;
import service.OrderModifiedRequest;
import enmu.OrderStatus;
import exception.BusinessException;
import exception.ExceptionCode;
import model.Item;
import model.Order;
import service.IOrderRepositoryService;
import service.IUpdateService;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

public class UpdateServiceImpl implements IUpdateService {
    private LocalTime localTime = LocalTime.now();
    /**
     * 修改订单
     * @param orderId
     * @param request
     * @return
     */
    @Override
    public Order updateOrder(Long orderId, OrderModifiedRequest request) {
        IOrderRepositoryService orderRepositoryService = new OrderRepositoryServiceImpl();
        /**
         * 根据id查询订单
         */
        Order order = orderRepositoryService.findById(String.valueOf(orderId));
        /**
         * 封装为list表
         */
        List<Order> orderList = new ArrayList<>();
        orderList.add(order);
        if (localTime == null) {
            localTime = LocalTime.from(order.getCreateTime());
        }
        if (order == null || order.getItems() == null || order.getItems().isEmpty()) {
            throw new BusinessException(ExceptionCode.ORDER_NOT_FOUND);
        }
        OrderStatus status = order.getStatus();
        if (status.equals(OrderStatus.CANCELLED) || status.equals(OrderStatus.PAID)) {
            throw new BusinessException(ExceptionCode.MODIFY_FORBIDDEN);
        }
        if (ModifiedType.FULL_REPLACE.equals(request.getModifiedType())) {//整单修改
        } else if (ModifiedType.PARTIAL_MODIFY.equals(request.getModifiedType())) {//部分修改
            handlePartialModification(order, request);
        } else {
            throw new IllegalArgumentException("Invalid modify type");
        }

        Order updateOrder = orderRepositoryService.save(order);

        return updateOrder;
    }



    private void handlePartialModification(Order order, OrderModifiedRequest request){
        //检查有效性
        validateItems(order.getItems());
        //历史优惠回溯
        rollbackHistoricalPromotions(order,request);
        //计算优惠
        applyNewPromotions(order);
    }

    /**
     * 计算优惠
     * @param order
     * @return
     */
    private void applyNewPromotions(Order order) {
        List<Item> items = order.getItems();
        double NoDrinkSum = items.stream().filter(i -> i.getType() != ItemType.DRINK)
                .mapToDouble(Item::getPrice).sum();
        double DrinkSum = items.stream().filter(i -> i.getType().equals(ItemType.DRINK))
                .mapToDouble(Item::getPrice).sum();
        double AllSum = NoDrinkSum+ DrinkSum;
        System.out.println("原价总价："+ AllSum);
        double promotion = promotion(items,true);
        double resultPrice = AllSum - promotion;
        order.setTotalPrice(resultPrice);
    }

    /**
     * 历史回溯
     * @param order
     * @param request
     * @return price
     */
    private double rollbackHistoricalPromotions(Order order, OrderModifiedRequest request) {
        List<Item> items = order.getItems();
        double NoDrinkSum = items.stream().filter(i -> i.getType() != ItemType.DRINK)
                .mapToDouble(Item::getPrice).sum();
        double DrinkSum = items.stream().filter(i -> i.getType().equals(ItemType.DRINK))
                .mapToDouble(Item::getPrice).sum();
        double AllSum = NoDrinkSum+ DrinkSum;
        System.out.println("原价总价："+ AllSum);
        double promotion = promotion(items,true);
        System.out.println("共优惠：" + promotion);
        double resultPrice = AllSum - promotion;
        System.out.println("应支付:" + resultPrice);
        return resultPrice;
    }

    /**
     * 有效性
     * @param modifiedItems
     */
    private void validateItems(List<Item> modifiedItems) {
        if (modifiedItems == null || modifiedItems.isEmpty()){
            throw new BusinessException(ExceptionCode.EMPTY);
        }
        //不能单独购买甜品
        validDessert(modifiedItems);
        //不能没有主食
        validMainFood(modifiedItems);
        long MainStream= modifiedItems.stream().filter(item -> ItemType.MAIN.equals(item.getType())).count();
        long DessertStream = modifiedItems.stream().filter(item -> ItemType.DESSERT.equals(item.getType())).count();
        long Drink = modifiedItems.stream().filter(item -> ItemType.DRINK.equals(item.getType())).count();
        if (MainStream == 0 && DessertStream > 0 && Drink == 0){
            throw new BusinessException(ExceptionCode.DESSERT_ALONE);
        }
        if (Drink > 0){
            if (localTime.getHour() >= 15 ){
                String iceId = "C004";
                List<Item> collect = modifiedItems.stream().filter(item -> iceId.equals(item.getId())).collect(Collectors.toList());
                if (!collect.isEmpty()){
                    modifiedItems.remove(collect);
                    throw new BusinessException(ExceptionCode.ITEM_INVALID);
                }
            }
        }
        if (modifiedItems.size() > 5 ){
            throw new BusinessException(ExceptionCode.TOO_MANY_ITEMS);
        }

    }
    private void validDessert(List<Item> items) {
        long countDessert = items.stream().filter(item -> ItemType.DESSERT.equals(item.getType())).count();
        long countMainFood = items.stream().filter(item -> ItemType.MAIN.equals(item.getType())).count();
        if (countDessert > 0 && countMainFood == 0) {
            throw new BusinessException(ExceptionCode.DESSERT_ALONE);
        }
    }
    private void validMainFood(List<Item> items) {
        long countMainFood = items.stream().filter(item -> ItemType.MAIN.equals(item.getType())).count();
        if (countMainFood == 0) {
            throw new BusinessException(ExceptionCode.NO_MAIN_FOOD);
        }
    }
    //计算促销总价
    private double promotion(List<Item> items,boolean Vip) {
        //套1
        long countHamburger = items.stream().filter(i -> "H001".equals(i.getId())).count();
        long countFries = items.stream().filter(i -> "F002".equals(i.getId())).count();
        //计算套餐数
        double countPackage = Math.min(countHamburger, countFries);
        double v1 = countPackage * 5;

        //套2
        List<Item> drinkList = items.stream().filter(i -> ItemType.DRINK.equals(i.getType())).collect(Collectors.toList());
        /**
         * coffee单价
         */
        Double CoffeePrice = drinkList.stream().filter(i -> "C004".equals(i.getId()))
                .map(Item::getPrice)//筛选出咖啡价格
                .findFirst() // 取第一个（Optional<Double>）
                .orElse(0.0); // 如果没有匹配项，返回默认值 0.0;
        /**
         * coke单价
         */
        Double CokePrice = drinkList.stream().filter(i -> "C005".equals(i.getId()))
                .map(Item::getPrice)//筛选出可乐价格
                .findFirst() // 取第一个（Optional<Double>）
                .orElse(0.0); // 如果没有匹配项，返回默认值 0.0;
        /**
         * orange单价
         */
        Double OrangePrice = drinkList.stream().filter(i -> "C006".equals(i.getId()))
                .map(Item::getPrice)//筛选出橙汁价格
                .findFirst() // 取第一个（Optional<Double>）
                .orElse(0.0); // 如果没有匹配项，返回默认值 0.0;
        /**
         * coffee，coke，orange杯数
         */
        long countCoffee = drinkList.stream().filter(i -> "C004".equals(i.getId())).count();
        long countCoke = drinkList.stream().filter(i -> "C005".equals(i.getId())).count();
        long countOrange = drinkList.stream().filter(i -> "C006".equals(i.getId())).count();
        /**
         * 促销价格
         */
        double halfCoffeePrice = (countCoffee / 2) * (CoffeePrice * 0.5);
        double halfCokePrice = (countCoke / 2) * (CokePrice * 0.5);
        double halfOrangePrice = (countOrange / 2) * (OrangePrice * 0.5);
        //第二杯优惠总价
        Double v2 = halfCoffeePrice+halfOrangePrice+halfCokePrice;
        double v3 = 0;
        if (Vip) {
            v3 = items.stream().mapToDouble(Item::getPrice).sum() * 0.1;
        }

        return v1+v2+v3;
    }
    }
